package com.example.mq.mqserver.core;

/*
 * 这个类用来实现路由转发的规则
 */
public class Router {
    //规定:
    //bindingKey 由 数字,字母,下划线组成,通过.来分隔,允许通配符*,#存在
    //形如: 123.abc.*._aa.#
    public boolean checkBindingKey(String bindingKey){
        for(int i = 0; i < bindingKey.length(); i++){
            char ch = bindingKey.charAt(i);
            if((ch >= 'a' && ch <= 'z') || (ch >= '0' && ch <= '9') || (ch >= 'A' && ch <= 'Z')){
                continue;
            }
            if(ch == '.' || ch == '_' || ch == '*' || ch == '#'){
                continue;
            }
            return false;
        }
        //这里处理通配符不合法的情况
        String[] words = bindingKey.split("\\.");
        for(int i = 0; i < words.length; i++){
            String word = words[i];
            if(word.length() > 1 && (word.contains("*") || word.contains("#"))){
                return false;
            }
            if(word.equals("#")){
                if(i + 1 < words.length && (words[i + 1].equals("#") || words[i + 1].equals("*"))){
                    return false;
                }
            }
        }
        return true;
    }

    //规定:
    //routingKey 由 数字,字母,下划线组成,通过.来分隔
    //形如: 123.abc._123
    public boolean checkRoutingKey(String routingKey){
        for(int i = 0; i < routingKey.length(); i++){
            char ch = routingKey.charAt(i);
            if((ch >= 'a' && ch <= 'z') || (ch >= '0' && ch <= '9') || (ch >= 'A' && ch <= 'Z')){
                continue;
            }
            if(ch == '.' || ch == '_' ){
                continue;
            }
            return false;
        }
        return true;
    }

    //进行路由判定
    public boolean route(ExchangeType exchangeType, String routingKey, String bindingKey){
        if(exchangeType == ExchangeType.FANOUT){
            return true;
        }
        if(exchangeType == ExchangeType.TOPIC){
            if(routeTopic(routingKey, bindingKey)){
                return true;
            }
        }
        return false;
    }

    //主题交换机的路由
    private boolean routeTopic(String routingKey, String bindingKey) {
        String[] routingTokens = routingKey.split("\\.");
        String[] bindingTokens = bindingKey.split("\\.");
        int routingIndex = 0;
        int bindingIndex = 0;
        while(routingIndex < routingTokens.length && bindingIndex < bindingTokens.length){
            if(bindingTokens[bindingIndex].equals("#")){
                if(bindingIndex == bindingTokens.length - 1){
                    return true;
                }else {
                    bindingIndex++;
                    for(int i = routingIndex; i < routingTokens.length; i++){
                        if(bindingTokens[bindingIndex].equals(routingTokens[routingIndex])){
                            break;
                        }
                    }
                    if(routingIndex == routingTokens.length){
                        return false;
                    }
                }
            }else{
                if(!routingTokens[routingIndex].equals(bindingTokens[bindingIndex])
                && !bindingTokens[bindingIndex].equals("*")){
                    return false;
                }
            }
            routingIndex++;
            bindingIndex++;
        }
        if(routingIndex == routingTokens.length && bindingIndex == bindingTokens.length){
            return true;
        }
        return false;
    }
}
